/*****************************************************************************
*    Ali Corp. All Rights Reserved. 2007 Copyright (C)
*
*    File:    slot.S
*
*    Description:    This file contains all code in standby mode.
*    History:
*           Date            Athor        Version          Reason
*	    ============	=============	=========	=================
*	1.	05.22.2007       zhaojian tang      Ver 0.1    Create file.
*	2.	28.03.2008		 Victor				Ver	0.2	 Support 16515 VFD panel
*****************************************************************************/
#include <hal/mips.h>
#include <sys_config.h>

#define TIMER_COMPARE_1S	(27000000 / 4)

//#define DIRECT_GPIO_POWER_ON		39

#ifndef	PAN_KEY_STANDBY
#define PAN_KEY_STANDBY			0xFFFF0008
#endif
#ifndef IRP_KEY_STANDBY
#define IRP_KEY_STANDBY			0x807fc03f
#endif
#ifndef IRP_KEY_STANDBY2
#define IRP_KEY_STANDBY2		0x60df708f
#endif

#define HAL_GPIO_I_DIR			0
#define HAL_GPIO_O_DIR			1

#define GPIO_REG_ARRAY_SIZE		5	// refer to gpio_dir_reg_array[], etc.


# MACRO: bin2ascii#define PAN_KEY_STANDBY			0xFFFF0008
#  reg b1: Input binary data.
#  reg d1: Output BCD code data.
# Internal:
#  t0: ;
#  t1: Primary higher 4 digital;
#  t2: Lower 4 bit digital;
#  t3: ;
#
		.macro	bin2ascii b1,d1
		andi	t0, \b1, 0xf0;
		srl		t0, 4;					# 6bits->2bits higher
		srl		t1, t0, 1;
		addu	t1, t0;					# Get the base: 00b=>0d, 01b=>1d, 10b=>3d, 11b=>4d
		sll		t2, t1, 3;
		sll		t3, t1, 1;
		addu	t3, t2;					# 10X: 0=>0, 1=>10, 2=>20, etc...
		subu	t2, \b1, t3;			# Get draft lower value to t2
		li		t0, 10;
		blt		t2, t0, 11f;			# If lower 4bits<10, finished
		nop
		addiu	t1, 1;					# Else higher+1, and lower-10.
		sub		t2, t0;
		blt		t2, t0, 11f;			# If lower 4bits<10, finished
		nop
		addiu	t1, 1;					# Else higher+1, and lower-10.
		sub		t2, t0;
11:		sll		t1, 4;
		or		\d1, t1, t2;
		.endm

# MACRO: get_led_array(reg dr)
#  reg dr: load led_array to dr.
#
		.macro	get_led_array dr
		la		\dr, led_array
		or		\dr, \dr, 0xa0000000	# ensure not use D-cache to load variable
		.endm


# MACRO: get_fp_power_key(reg dr)
#  reg dr: load fp power key to dr.
#
		.macro	get_fp_power_key dr
		li		\dr, PAN_KEY_STANDBY
		.endm


# MACRO: get_pan_hw_info(reg dr)
#  reg dr: load pan_hw_info to dr.
#
		.macro	get_pan_hw_info dr
		la		\dr, pan_hw_info
		or		\dr, \dr, 0xa0000000	# ensure not use D-cache to load variable
		.endm


# MACRO: get_ir_power_key(reg dr)
#  reg dr: load ir power key to dr.
#
		.macro	get_ir_power_key dr
		li		\dr, IRP_KEY_STANDBY
		.endm

		.macro	get_ir_power_key2 dr
		li		\dr, IRP_KEY_STANDBY2
		.endm

		.macro	get_led_dot_bmp dr
		li		\dr, 0xfe
		.endm

		.macro	gettimerdata dr
		li		t1, 0x80000700
		lw		\dr, 0(t1)
		.endm
		
		.macro	settimerdata sr
		li		t1, 0x80000700			# Set REF head address
		sw		\sr,0(t1)	
		.endm

# ------------------------------------------------------------------------------
# void hal_gpio_set_dir(pos, dir)
#
# input:
#	a0: gpio pos
#   a1: gpio dir
#
# used:
#	t0: dir reg addr
#	t1
#	t2
# ------------------------------------------------------------------------------
        .globl  hal_gpio_set_dir
        .ent    hal_gpio_set_dir
   		.set	noreorder
hal_gpio_set_dir:
		srl		t1, a0, 5		# t1: index in gpio_dir_reg_array[]
		li		t2, GPIO_REG_ARRAY_SIZE
		bgeu	t1, t2, 1f
		nop
		
		la		t2, gpio_dir_reg_array
		or		t2, t2, 0xa0000000	# ensure not use D-cache to load variable
		sll		t1, t1, 1
		addu	t1, t2, t1		# t1: &gpio_dir_reg_array[index]

		lhu		t2, 0(t1)		# t2: gpio_dir_reg_array[index]
		lui		t0, 0xb800
		addu	t0, t0, t2		# t0: dir reg addr
		
		andi	a0, 0x1f
        lw      t1, 0(t0)		# t1: dir register
        li      t2, 1
        sll		t2, t2, a0		# t2: bit mask
        
		not		t2, t2			# clean bit
		and		t1, t1, t2

		andi	a1, 1			# set bit
		sll		a1, a1, a0
        or      t1, t1, a1
        sw      t1, 0(t0)
        nop
1:
        jr      ra
        nop
   		.set 	reorder
        .end    hal_gpio_set_dir

# ------------------------------------------------------------------------------
# void hal_gpio_set_bit(pos, val)
#
# input:
#	a0: gpio pos
#	a1: gpio val
#
# used:
#	t0: output reg addr
#	t1
#	t2
# ------------------------------------------------------------------------------
        .globl  hal_gpio_set_bit
        .ent    hal_gpio_set_bit
   		.set	noreorder
hal_gpio_set_bit:
		srl		t1, a0, 5		# t1: index in gpio_do_reg_array[]
		li		t2, GPIO_REG_ARRAY_SIZE
		bgeu	t1, t2, 1f
		nop
		
		la		t2, gpio_do_reg_array
		or		t2, t2, 0xa0000000	# ensure not use D-cache to load variable
		sll		t1, t1, 1
		addu	t1, t2, t1		# t1: &gpio_do_reg_array[index]

		lhu		t2, 0(t1)		# t2: gpio_do_reg_array[index]
		lui		t0, 0xb800
		addu	t0, t0, t2		# t0: output reg addr

		andi	a0, 0x1f
        lw      t1, 0(t0)		# t1: output register
        li      t2, 1
        sll		t2, t2, a0		# t2: bit mask
        
		not		t2, t2			# clean bit
		and		t1, t1, t2

		andi	a1, 1			# set bit
		sll		a1, a1, a0
        or      t1, t1, a1
        sw      t1, 0(t0)
        nop
1:
        jr      ra
        nop
        .set 	reorder
        .end    hal_gpio_set_bit

#--------------------------------------------------------------------
#
#   Function_Name: sys_preboot
#     This function used only for board dedicated issue patch, just as
#     turn off LED GPIO, if you want do other patch about chipset,
#     please added into _Init_Chipset in boot.S.
#--------------------------------------------------------------------
		.globl  sys_preboot
		.ent	sys_preboot
		.set 	noreorder
sys_preboot:
#ifdef DDR_POWER_CONTROL_ENABLE
		move	t4, ra							# t4: save ra
# POWER ON DDR
		li		a0, DDR_POWER_CTL_GPIO_POS		# a0: gpio pos
		jal		hal_gpio_set_bit				# set gpio output
		li		a1, DDR_POWER_CTL_GPIO_POLAR	# a1: active polarity

		li		a0, DDR_POWER_CTL_GPIO_POS		# a0: gpio pos
		jal 	hal_gpio_set_dir				# set gpio dir
		li		a1, HAL_GPIO_O_DIR				# a1: gpio dir

		move	ra, t4
#endif
		jr		ra
		nop
		.set 	reorder
		.end	sys_preboot



		.globl  sys_prestandby
		.ent	sys_prestandby
		.set	noreorder
sys_prestandby:
		move	k0, ra
		nop
		jal		ini_ir							# Init IR
		nop
#ifdef STANDBY_POWER_GPIO_DETECT
#add on 2011-10-14 #######################################
    li		a0, FP_STANDBY_GPIO_NUM		# a0: gpio pos
    li		a1, HAL_GPIO_I_DIR				# a1: gpio dir
		jal 	hal_gpio_set_dir				  # set gpio dir
		
		li		a0, FP_STANDBY_GPIO_NUM	  # a0: gpio pos
		li		a1, 1	                    # a1: active polarity
		jal		hal_gpio_set_bit				  # set gpio output
#add on 2011-10-14 #######################################	
#else	
		jal     ini_panel
#endif		
		nop
#ifdef DDR_POWER_CONTROL_ENABLE
# POWER OFF DDR
		li		a0, DDR_POWER_CTL_GPIO_POS		# a0: gpio pos
		li		a1, DDR_POWER_CTL_GPIO_POLAR	# a1: gpio polarity
		jal		hal_gpio_set_bit				# set gpio output
		xori	a1, 1							# a1: inactive polarity

		li		a0, DDR_POWER_CTL_GPIO_POS		# a0: gpio pos
		jal 	hal_gpio_set_dir				# set gpio dir
		li		a1, HAL_GPIO_O_DIR				# a1: gpio dir
#endif
		move 	ra, k0
		nop		
		jr		ra
		nop
		.set reorder
		.end sys_prestandby


		.globl	sys_poststandby
		.ent	sys_poststandby
		.set noreorder
sys_poststandby:
		move	k1, ra
		nop
		move	ra, k1
		nop
		jr		ra
		nop
		.set reorder
		.end sys_poststandby
		
#define PAN_KEY_EXIT_STANDBY 0x44
#define PAN_KEY_MASK_STANDBY 0xff

		.globl	sys_standby_process
		.ent	sys_standby_process
sys_standby_process:		
		.set	noreorder
		mfc0	t0, C0_COUNT			# Check scan or not
		li		t1, (TIMER_COMPARE_1S>>8)	# 1/256 second per LED
		subu	       t2, s4, t0
		bgtu	       t2, t1, real_scan
		nop
		li		v0,0
		jr		ra
		nop
real_scan:
		addu	s4, t1					# 1/256 second per LED
		move	k0, ra
#ifdef STANDBY_POWER_GPIO_DETECT		
#add on 2011-10-14###################################		
		li t0, 0xb80000f0
		lw t1, 0(t0)
		li t0, 1
		sll t0, 1
		and t2, t1, t0
		li t0, 0
		beq t0, t2, exit_standby	
#add on 2011-10-14###################################
#else		
		jal		check_key_panel
#endif	
		nop
		li		t3, PAN_KEY_EXIT_STANDBY
		and     v0, v0, PAN_KEY_MASK_STANDBY
		bne		v0, t3, 3f
		nop 
		
out_process:
		li		s8, 0xdeadbead			# Set the flag about time to REF
		jal 	exit_standby			# Power key press, exit standby
		nop
3:
		move	ra, k0
		jr		ra
		nop
		.set reorder
		.end sys_standby_process


#define SYS_IC_NB_BASE_H		0xb800
#define SYS_IC_NB_EISR			0x30
#define SYS_IC_SB_IRC_BITIE 	0x80000
#define SYS_IC_PMU_BASE 	    0xb8018d00
#define SYS_IC_PMU_PRS_KEY_CFG 	0xb0
#define SYS_IC_KEY_PRS_ST_NORM	0x100000
#define SYS_IC_SB_PMU_KEY_BITIE		0x1000000
# for HDMI CEC:
#define SYS_IC_HDMI_BITIE		0x2000
		.globl	sys_standby_exception
		.ent	sys_standby_exception
sys_standby_exception:	
		.set	noreorder
#if (SYS_CHIP_MODULE != ALI_S3601)
		la		t1, 3f					# Running in cache
		sll 	t1, 4
		srl 	t1, 4
		lui 	t0, 0x8000
		or		t1, t0
		jr		t1
		nop
#endif
3:
		lui 	t1,SYS_IC_NB_BASE_H
		lw		t2,SYS_IC_NB_EISR(t1)
		li		t0, SYS_IC_SB_IRC_BITIE
		and 	 t3,t2,t0				# IR interrupt?
		bnez	 t3,2f
		nop
		lw      t1 ,  0xb8000000
		and     t1 ,  0xffff0000
		li      t2 ,  0x38110000
		bne     t1 ,  t2 ,5f
		nop
		lw      t1 ,  0xb8000000
		li      t2 ,   0xffff
		and     t1 ,  t2
		beqz    t1 ,  5f
		nop
		lui 	t1,SYS_IC_NB_BASE_H
		lw		t2,SYS_IC_NB_EISR(t1)
		li		 t0, SYS_IC_SB_PMU_KEY_BITIE # pmu power key interrupt
		and 	 t3,t2,t0	
		beqz	 t3,5f
		nop
		
     
   
       li    t1 ,  SYS_IC_PMU_BASE
       li    t2 ,  SYS_IC_KEY_PRS_ST_NORM
       
       lw     t3 ,  SYS_IC_PMU_PRS_KEY_CFG(t1) 
       or     t3 ,SYS_IC_KEY_PRS_ST_NORM
       sw     t3 ,  SYS_IC_PMU_PRS_KEY_CFG(t1)    #clear key interrupt 
       li  s8 , 0xdeadbead
       jal 	exit_standby
	   nop 
5:	   
		li		s8, 0xdeadbeef			# Set the flag about enter IC stanby again
		jal 	exit_standby
		nop
2:
		
		jal 	get_ir					# Get IR code
		
		nop
#if !(defined(PANEL_16312_VFD) || defined(PANEL_16515_VFD))		
		get_ir_power_key t1				# Check POWER remote key code
		beq		v0, t1, 3f

		get_ir_power_key2 t1
		bne		v0, t1, 4f

#else
		li		t1, IRP_KEY_STANDBY
		bne		v0, t1, 4f		
#endif		
		nop
3:		
		li		s8, 0xdeadbead			# Set the flag about time to REF
		jal 	exit_standby
		nop
4:
		nop
					nop
		.set mips3
		eret
		.set mips1
		nop
		nop
		.set reorder
		.end sys_standby_exception

#if !defined(PANEL_16515_VFD)
led_array:
			 /*  '0'   '1'   '2'   '3'*/
		.byte	0x03, 0x9f, 0x25, 0x0d
			 /*  '4'   '5'   '6'   '7'*/
		.byte	0x99, 0x49, 0x41, 0x1f
			 /*  '8'   '9'   'O'   'F'*/
		.byte	0x01, 0x09, 0x03, 0x71
			 /*  ':'   '-'   '_'   ' '*/
		.byte	0x01, 0xfd, 0xef, 0xff
#else


led_array:
			 /*     '0'         '1'         '2'         '3'  */
		.byte	0x31, 0x46, 0x10, 0x02, 0xd1, 0x45, 0xd1, 0x43
			 /*     '4'         '5'         '6'         '7'  */
		.byte	0xf0, 0x03, 0xe1, 0x43, 0xe1, 0x47, 0x11, 0x02
			 /*     '8'         '9'         'O'         'F'  */
		.byte	0xf1, 0x47, 0xf1, 0x43, 0x31, 0x46, 0xe1, 0x05
			 /*     ':'         '-'         '_'         ' '  */
		.byte	0x80, 0x00, 0xc0, 0x01, 0x00, 0x40, 0x00, 0x00

#endif

gpio_dir_reg_array:
		.half	0x0058, 0x00d8, 0x00f8, 0x0358, 0x0458

gpio_di_reg_array:
		.half	0x0050, 0x00d0, 0x00f0, 0x0350, 0x0450

gpio_do_reg_array:
		.half	0x0054, 0x00d4, 0x00f4, 0x0354, 0x0454

